﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;


[assembly: TagPrefix("TrainingsApp.Controls.GridViewExt", "GridViewExt")]
[assembly: System.Web.UI.WebResource("TrainingsApp.Controls.GridViewExt.Resource.btngo.gif", "image/gif")]
[assembly: System.Web.UI.WebResource("TrainingsApp.Controls.GridViewExt.Resource.btnSetting.gif", "image/gif")]
[assembly: System.Web.UI.WebResource("TrainingsApp.Controls.GridViewExt.Resource.GridViewExt.css", "text/css")]
[assembly: System.Web.UI.WebResource("TrainingsApp.Controls.GridViewExt.Resource.GridViewExt.js", "text/javascript")]

namespace TrainingsApp.Controls.GridViewExt
{
    public enum OrderTypeEnum
    {
        /// <summary>
        /// 升序：1
        /// </summary>
        Asc,
        /// <summary>
        /// 降序：2
        /// </summary>
        Desc
    }

    public delegate void BindDataEventHandler();

    [ToolboxData("<{0}:GridViewExt runat=server></{0}:GridViewExt>")]
    [ToolboxBitmap(typeof(GridViewExt), "Resource.GridViewExt.bmp")]
    public class GridViewExt : System.Web.UI.WebControls.GridView
    {
        public event BindDataEventHandler BindData;

        private TextBox tbSetPage;
        private TextBox txtPage;

        /// <summary>
        /// 总记录数
        /// </summary>
        public int RecordCount
        {
            get
            {
                object o = ViewState["RecordCount"];
                return o == null ? 0 : Convert.ToInt32(o);
            }
            set
            {
                ViewState["RecordCount"] = value;
            }
        }

        ///// <summary>
        ///// 获取排序方式
        ///// </summary>
        //public new ListSortDirection SortDirection
        //{
        //    get
        //    {
        //        if (ViewState["SortDirection"] != null)

        //            if (Enum.IsDefined(typeof(ListSortDirection), ViewState["SortDirection"]))
        //                return (ListSortDirection)ViewState["SortDirection"];
        //            else
        //                throw new Exception(ViewState["SortDirection"] + " is not defined");
        //        else
        //            return ListSortDirection.Ascending;
        //    }
        //}

        public override string SortExpression
        {
            get
            {
                if (ViewState["SortExpression"] != null && !string.IsNullOrEmpty(ViewState["SortExpression"].ToString()))
                {
                    return string.Format("{0} {1}", ViewState["SortExpression"], ViewState["SortDirection"]);
                }

                return "";
            }
        }

        public string SortExp2
        {
            get
            {
                return ViewState["SortExpression"] != null ? ViewState["SortExpression"].ToString() : string.Empty;

            }
        }
        public ListSortDirection SortDir2
        {
            get
            {
                ListSortDirection dir = ListSortDirection.Ascending;
                if (ViewState["SortDir2"] == null)
                {
                    ViewState["SortDir2"] = "ASC";
                }
                else
                {
                    dir = string.Compare(ViewState["SortDir2"].ToString().Trim(), "ASC") == 0 ? ListSortDirection.Descending : ListSortDirection.Ascending;
                    if (string.Compare(ViewState["SortDir2"].ToString().Trim(), "ASC") == 0)
                    {
                        ViewState["SortDir2"] = "DESC";
                    }
                    else
                    {
                        ViewState["SortDir2"] = "ASC";
                    }
                }
                return dir;
            }
        }

        /// <summary>
        /// 总页数
        /// </summary>
        public override int PageCount
        {
            get
            {
                return RecordCount % PageSize == 0 ? RecordCount / PageSize : RecordCount / PageSize + 1;
                ;
            }
        }

        /// <summary>
        /// 当前第几页
        /// </summary>
        public override int PageIndex
        {
            get
            {
                object o = ViewState["PageIndex"];
                return o == null ? 1 : Convert.ToInt32(o);
            }
            set
            {
                ViewState["PageIndex"] = value;
            }
        }

        /// <summary>
        /// 行标记数据项
        /// </summary>
        [DefaultValue("")]
        public string RowValueField
        {
            get
            {
                return ViewState["RowValueField"] == null ? "" : ViewState["RowValueField"].ToString();
            }
            set
            {
                ViewState["RowValueField"] = value;
            }
        }

        /// <summary>
        /// 行标记前缀
        /// </summary>
        public string RowIdPrefix
        {
            get
            {
                return ViewState["RowIdPrefix"] == null ? "tr_" : ViewState["RowIdPrefix"].ToString();
            }
            set
            {
                ViewState["RowIdPrefix"] = value;
            }
        }

        /// <summary>
        /// 分页记录数是否保存，影响其他表格
        /// </summary>
        public bool PermanentSetting
        {
            get
            {
                object o = ViewState["PermanentSetting"];
                return o == null ? false : Convert.ToBoolean(o);
            }
            set
            {
                ViewState["PermanentSetting"] = value;
            }
        }

        /// <summary>
        /// 每页显示记录数
        /// </summary>
        public override int PageSize
        {
            get
            {
                if (!this.DesignMode && PermanentSetting)
                {
                    HttpCookie cookie = HttpContext.Current.Request.Cookies["CPageSize"];
                    if (cookie != null)
                    {
                        return int.Parse(cookie.Value);
                    }
                }

                object obj2 = this.ViewState["PageSize"];
                if (obj2 != null)
                {
                    return (int)obj2;
                }

                return 10;
            }
            set
            {
                if (this.PageSize != value)
                {
                    this.ViewState["PageSize"] = value;
                    if (!this.DesignMode && PermanentSetting)
                    {
                        HttpCookie cookie = HttpContext.Current.Request.Cookies["CPageSize"];
                        if (cookie == null)
                        {
                            cookie = new HttpCookie("CPageSize", value.ToString());
                            cookie.Expires = DateTime.Now.AddYears(1);
                        }
                        else
                        {
                            cookie.Value = value.ToString();
                        }

                        HttpContext.Current.Response.Cookies.Add(cookie);
                    }
                }
            }
        }

        public new bool AllowPaging
        {
            get
            {
                object o = ViewState["AllowPagings"];
                return o == null ? false : Convert.ToBoolean(o);
            }
            set
            {
                ViewState["AllowPagings"] = value;
            }
        }

        public override string EmptyDataText
        {
            get
            {
                return string.IsNullOrEmpty(base.EmptyDataText) ? "查询结束,未找到任何相关记录" : base.EmptyDataText;
                ;
            }
            set
            {
                base.EmptyDataText = string.IsNullOrEmpty(value) ? "查询结束,未找到任何相关记录" : value;
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            //去掉表格外的div
            this.PrepareControlHierarchy();
            this.RenderContents(writer);
        }

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);
        }

        protected override void OnRowDataBound(GridViewRowEventArgs e)
        {
            if (!this.DesignMode)
            {
                if (e.Row.RowType == DataControlRowType.EmptyDataRow)
                {
                    e.Row.Attributes.Add("id", "-2");
                }


                else if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    if (this.RowValueField.Length > 0)
                    {
                        Type t = e.Row.DataItem.GetType();
                        string val = Convert.ToString(t.GetProperty(RowValueField).GetValue(e.Row.DataItem, null));
                        if (!string.IsNullOrEmpty(val))
                        {
                            e.Row.Attributes.Add("id", RowIdPrefix + val.ToString());
                        }
                    }

                }

                //else if (e.Row.RowType == DataControlRowType.DataRow)
                //{
                //    if (this.RowValueField.Length > 0)
                //    {
                //        PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(e.Row.DataItem);
                //        object val = pdc.Find(this.RowValueField, true).GetValue(e.Row.DataItem);
                //        if (val != null && val.ToString().Length > 0)
                //            e.Row.Attributes.Add("id", RowIdPrefix + val.ToString());
                //    }
                //}
            }


            base.OnRowDataBound(e);
        }

        protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
        {
            int pRes = base.CreateChildControls(dataSource, dataBinding);
            if (dataSource != null && PageCount > 1 && this.AllowPaging)
            {
                if (dataSource.GetEnumerator().MoveNext())
                {
                    OnCreateCustomPageRow();
                }
            }

            return pRes;
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (this.Page != null)
            {
                if (!this.Page.ClientScript.IsClientScriptIncludeRegistered(this.GetType(), "GridViewExtJS"))
                {
                    this.Page.ClientScript.RegisterClientScriptInclude(typeof(GridViewExt), "GridViewExtJS", this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "TrainingsApp.Controls.GridViewExt.Resource.GridViewExt.js"));

                    System.Web.UI.HtmlControls.HtmlLink link = new System.Web.UI.HtmlControls.HtmlLink();
                    link.Attributes["type"] = "text/css";
                    link.Attributes["rel"] = "stylesheet";
                    link.Attributes["href"] = Page.ClientScript.GetWebResourceUrl(this.GetType(), "TrainingsApp.Controls.GridViewExt.Resource.GridViewExt.css");
                    this.Page.Header.Controls.Add(link);
                }
            }

            this.CssClass = "tablelist";
            this.CellSpacing = 0;
            this.CellPadding = 1;

            base.OnPreRender(e);
        }

        protected override void OnRowCreated(GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                e.Row.CssClass = "toptitle";
            }
            else if (e.Row.RowType == DataControlRowType.EmptyDataRow)
            {
                e.Row.CssClass = "listr4";
            }
            else if (e.Row.RowType == DataControlRowType.DataRow)
            {
                //for (int i = 0; i < this.Columns.Count - 1; i++)
                //{
                //    BoundField bf = this.Columns[i] as BoundField;
                //    if (bf != null)
                //    {
                //        e.Row.Cells[i].Attributes.Add("field", bf.DataField);
                //    }
                //}

                // 额外样式定义
                e.Row.Attributes["onmouseover"] = "oldc=this.className;this.className=\"listr3\"";
                e.Row.Attributes["onmouseout"] = "this.className=oldc";

                //if (EnableDoubleClick)
                //{
                //    e.Row.Attributes["style"] = "cursor:pointer";
                //    e.Row.Attributes["title"] = "双击查看当前行信息";
                //    Control link = e.Row.FindControl("lbtView");
                //    if (link != null)
                //        e.Row.Attributes.Add("ondblclick", "document.getElementById['" + link.ClientID + "'].click();");
                //}

                e.Row.CssClass = e.Row.RowState == DataControlRowState.Alternate ? "listr2" : "listr1";
            }

            base.OnRowCreated(e);
        }

        protected override void OnRowCommand(GridViewCommandEventArgs e)
        {
            base.OnRowCommand(e);

            if (e.CommandName == "del")
                OnDataBind();
        }

        protected override void OnPageIndexChanging(GridViewPageEventArgs e)
        {
        }

        public void OnCreateCustomPageRow()
        {
            GridViewRow row = CreateRow();
            if (row != null)
            {
                Table table = this.Controls[0] as Table;
                if (table != null)
                {
                    CreateCustomPageRow(table, row);
                }
            }
        }

        private void CreateCustomPageRow(Table table, GridViewRow row)
        {
            //定义四个按扭表示"上一页","下一页","首页","尾页"
            LinkButton btnFirst = new LinkButton();
            LinkButton btnPrev = new LinkButton();
            LinkButton btnNext = new LinkButton();
            LinkButton btnLast = new LinkButton();

            //新建一行作为分页行
            TableCell tc = new TableCell();

            tc.ColumnSpan = this.HeaderRow.Cells.Count;

            btnFirst.Text = "[首页]";
            btnPrev.Text = "[上页]";
            btnNext.Text = "[下页]";
            btnLast.Text = "[末页]";

            btnFirst.Command += new CommandEventHandler(NavigateToPage);
            btnPrev.Command += new CommandEventHandler(NavigateToPage);
            btnNext.Command += new CommandEventHandler(NavigateToPage);
            btnLast.Command += new CommandEventHandler(NavigateToPage);

            btnFirst.CommandArgument = "First";
            btnPrev.CommandArgument = "Prev";
            btnNext.CommandArgument = "Next";
            btnLast.CommandArgument = "Last";

            //当前页是第一页,则"上一页"按扭设为无效
            if (this.PageIndex <= 1)
            {
                btnFirst.Enabled = btnPrev.Enabled = false;
            }
            else
            {
                btnFirst.Enabled = btnPrev.Enabled = true;
            }

            //当前页是尾页,则"下一页"按扭设为无效
            if (this.PageIndex >= PageCount)
            {
                btnNext.Enabled = btnLast.Enabled = false;
            }
            else
            {
                btnNext.Enabled = btnLast.Enabled = true;
            }

            //将以上两个分页按扭添加到分页行内
            tc.Controls.Add(btnFirst);
            tc.Controls.Add(new LiteralControl("&nbsp;|&nbsp;"));
            tc.Controls.Add(btnPrev);
            tc.Controls.Add(new LiteralControl("&nbsp;|&nbsp;"));
            tc.Controls.Add(btnNext);
            tc.Controls.Add(new LiteralControl("&nbsp;|&nbsp;"));
            tc.Controls.Add(btnLast);
            tc.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));

            tc.Controls.Add(new LiteralControl("当前第<font color='red'>&nbsp;" + (this.PageIndex).ToString() + "&nbsp;</font>页&nbsp;"));
            tc.Controls.Add(new LiteralControl("&nbsp;&nbsp;<font color='red'>"));
            tc.Controls.Add(new LiteralControl((this.PageIndex).ToString() + "</font>/" + this.PageCount.ToString()));
            tc.Controls.Add(new LiteralControl("&nbsp;&nbsp;&nbsp;共&nbsp;" + this.RecordCount.ToString()));
            tc.Controls.Add(new LiteralControl("&nbsp;条&nbsp;&nbsp;跳转"));

            txtPage = new TextBox();
            txtPage.ID = "txtPage";
            txtPage.CssClass = "pagego";
            txtPage.Text = (this.PageIndex).ToString();
            tc.Controls.Add(txtPage);
            tc.Controls.Add(new LiteralControl("&nbsp;页&nbsp;"));

            ImageButton btnGo = new ImageButton();
            btnGo.CommandArgument = "btnGo";
            btnGo.ImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "TrainingsApp.Controls.GridViewExt.Resource.btngo.gif");
            btnGo.Command += new CommandEventHandler(NavigateToPage);
            tc.Controls.Add(btnGo);

            tc.Controls.Add(new LiteralControl("&nbsp;每页显示&nbsp;"));
            tbSetPage = new TextBox();
            tbSetPage.CssClass = "pagego";
            tbSetPage.Text = this.PageSize.ToString();
            tbSetPage.ID = "tbSetPage";
            tc.Controls.Add(tbSetPage);
            tc.Controls.Add(new LiteralControl("&nbsp;条&nbsp;&nbsp;"));

            ImageButton btnSetPage = new ImageButton();
            btnSetPage.CommandArgument = "btnSetPage";
            btnSetPage.ImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "TrainingsApp.Controls.GridViewExt.Resource.btnSetting.gif");
            btnSetPage.Command += new CommandEventHandler(NavigateToPage);
            tc.Controls.Add(btnSetPage);

            row.Controls.Add(tc);
            row.Attributes.Add("align", "center");
            row.Attributes.Add("valign", "bottom");

            table.Rows.Add(row);
        }

        private GridViewRow CreateRow()
        {
            GridViewRow row = this.CreateRow(-3, -1, DataControlRowType.Pager, DataControlRowState.Normal);
            row.Height = 25;
            return row;
        }

        public void NavigateToPage(object sender, CommandEventArgs e)
        {
            switch (e.CommandArgument.ToString())
            {
                case "Prev":
                    if (this.PageIndex > 1)
                    {
                        this.PageIndex -= 1;

                    }
                    break;
                case "Next":
                    if (this.PageIndex < this.PageCount)
                    {
                        this.PageIndex += 1;

                    }
                    break;
                case "First":
                    this.PageIndex = 1;
                    break;
                case "Last":
                    this.PageIndex = this.PageCount;
                    break;
                case "btnGo":
                    int iPage = 1;
                    if (!Int32.TryParse(txtPage.Text, out iPage))
                    {
                        iPage = 1;
                    }

                    iPage--;

                    if (iPage < 1)
                    {
                        iPage = 1;
                    }

                    if (iPage >= PageCount)
                    {
                        iPage = this.PageCount;
                        this.txtPage.Text = iPage.ToString();
                    }

                    this.PageIndex = iPage;
                    break;
                case "btnSetPage":
                    int iSize = 0;
                    if (Int32.TryParse(tbSetPage.Text, out iSize))
                    {
                        if (iSize > 0)
                        {
                            this.PageSize = iSize;

                            if (!Int32.TryParse(txtPage.Text, out iPage))
                            {
                                iPage = 1;
                            }

                            iPage--;

                            if (iPage < 1)
                            {
                                iPage = 1;
                            }

                            if (iPage >= PageCount)
                            {
                                iPage = this.PageCount;
                                this.txtPage.Text = iPage.ToString();
                            }

                            this.PageIndex = iPage;
                        }
                    }

                    break;
                default:
                    break;
            }

            OnDataBind();//绑定数据
        }

        public void DeleteRow(string rowId)
        {
            Page.ClientScript.RegisterStartupScript(typeof(string), "js", string.Format("<script>delete_row('{0}',{1})</script>", rowId, this.ClientID));

        }

        protected override void OnSorting(GridViewSortEventArgs e)
        {
            if (ViewState["SortExpression"] != null && ViewState["SortExpression"].ToString() == e.SortExpression)
            {
                if (ViewState["SortDirection"] != null && (OrderTypeEnum)ViewState["SortDirection"] == OrderTypeEnum.Desc)
                {
                    ViewState["SortDirection"] = OrderTypeEnum.Asc;
                }
                else
                {
                    ViewState["SortDirection"] = OrderTypeEnum.Desc;
                }
            }
            else
            {
                ViewState["SortExpression"] = e.SortExpression;

                if (ViewState["SortDirection"] != null && (OrderTypeEnum)ViewState["SortDirection"] == OrderTypeEnum.Desc)
                {
                    ViewState["SortDirection"] = OrderTypeEnum.Asc;
                }
                else
                {
                    ViewState["SortDirection"] = OrderTypeEnum.Desc;
                }
            }

            OnDataBind();
        }

        protected void OnDataBind()
        {
            if (BindData != null)
            {
                BindData();
            }
        }
    }
}